﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace Com.Core.Helps
{
    public static class HttpClientHelper
    {
        public static string InvokeApi(string serverUri, IDictionary<string, string> para, string method = "get")
        {
            if (serverUri.Contains("?")) serverUri = serverUri.Substring(0, serverUri.IndexOf('?') + 1);
            if ("get".Equals(method)) return DoGet(serverUri, para);
            if ("post".Equals(method)) return DoPost(serverUri, para);
            return "error";
        }

        public static string DoGet(string serverUri, IDictionary<string, string> para)
        {
            if (null != para && para.Count > 0)
            {
                serverUri += serverUri.Contains("?") ? "&" + BuildQuery(para) : "?" + BuildQuery(para);
            }
            HttpClient client = new HttpClient();
            string content = client.GetStringAsync(serverUri).Result;
            return content;
        }

        public static string DoPost(string serverUri, IDictionary<string, string> para)
        {
            var parastring = new FormUrlEncodedContent(para);
            HttpClient client = new HttpClient();
            var aa = client.PostAsync(serverUri,parastring);
            return aa.Result.Content.ReadAsStringAsync().Result;
        }

        public static string BuildQuery(IDictionary<string, string> parameters)
        {
            StringBuilder postData = new StringBuilder();
            bool hasParam = false;

            IEnumerator<KeyValuePair<string, string>> dem = parameters.GetEnumerator();
            while (dem.MoveNext())
            {
                string name = dem.Current.Key;
                string value = dem.Current.Value;
                // 忽略参数名或参数值为空的参数
                if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
                {
                    if (hasParam)
                    {
                        postData.Append("&");
                    }

                    postData.Append(name);
                    postData.Append("=");
                    postData.Append(UrlEncode(value, Encoding.UTF8));
                    hasParam = true;
                }
            }

            return postData.ToString();
        }

        public static string DoPost(string uri, string str)
        {
            Encoding encoding = Encoding.UTF8;
            byte[] bytes = encoding.GetBytes(str);
            var httpWebRequest = (HttpWebRequest) WebRequest.Create(uri);
            httpWebRequest.ContentType = "application/x-www-form-urlencoded";
            httpWebRequest.ContentLength = bytes.Length;
            httpWebRequest.Method = "POST";
            using (Stream reqStream = httpWebRequest.GetRequestStream())
            {
                reqStream.Write(bytes, 0, bytes.Length);
            }
            using (WebResponse webResponse = httpWebRequest.GetResponse())
            {
                Stream responseStream = webResponse.GetResponseStream();
                var reader=new StreamReader(responseStream);
                return reader.ReadToEnd();
            }
        }

        /**
         * C#的URL encoding有两个问题：
         * 1.左右括号没有转移（Java的URLEncoder.encode有）
         * 2.转移符合都是小写的，Java是大写的
         */
        private static string UrlEncode(string str, Encoding e)
        {
            if (str == null)
            {
                return null;
            }

            // ReSharper disable once PossibleNullReferenceException
            String stringToEncode = HttpUtility.UrlEncode(str, e).Replace("+", "%20").Replace("*", "%2A").Replace("(", "%28").Replace(")", "%29");
            return RegUrlEncoding.Replace(stringToEncode, m => m.Value.ToUpperInvariant());
        }

        private static readonly Regex RegUrlEncoding = new Regex(@"%[a-f0-9]{2}");
    }
}
